home *** CD-ROM | disk | FTP | other *** search
- NAME msuz10
- ; file MSUZ10.ASM
- include mssdef.h
- ; Copyright (C) 1982,1991, Trustees of Columbia University in the
- ; City of New York. Permission is granted to any individual or
- ; institution to use, copy, or redistribute this software as long as
- ; it is not sold for profit and this copyright notice is retained.
- ; Kermit system dependent module for Heath/Zenith Z100
- ; Keyboard translator, by Joe R. Doupnik, Dec 1986
- ; with contributions from David L. Knoell.
- ; Adapted for the Z-100 by Bo G. Gedda, May 1990
- ; Edit history
- ; 2 March 1991 version 3.10
- ; Last edit 20 August 1992
- ; Kverb \kscroll (F11) added
- ; Bo Gedda
- ;
- ;
-
- public keybd, dfkey, shkey, msuinit, kbcodes, keycom, dosflg, dosflg1
-
- ; some definitions
-
- shift equ 200h ; IBM, synonym for right or left shift
- control equ 400h ; IBM, synonym for control shift
- alt equ 800h ; IBM, synonym for alt shift
-
- maxkeys equ 200 ; maximum number of key definitions
- maxstng equ 128 ; maximum number of multi-char strings
- stbuflen equ 1000 ; length of string buffer (bytes)
-
- verb equ 8000h ; dirlist flag: use verb action table
- strng equ 4000h ; dirlist flag: use string action table
- scan equ 100h ; keycode flag: code is scan not ascii
- braceop equ 7bh ; opening curly brace
- bracecl equ 7dh ; closing curly brace
-
- ; Z-100 Keyboard ports
- keydat equ 0f4h ; data
- keycmd equ 0f5h ; command
- keystat equ keycmd ; status
-
- ; Z-100 Keyboard status masks
- KPR equ 2 ; 00000010b, ready if this is NOT set
- KDA equ 1 ; 00000001b, data available if set
-
- ; Z-100 Keyboard commands
- keyrst equ 00h ; reset
- keyrpon equ 01h ; auto repeat on
- keyrpof equ 02h ; auto repeat off
- keyclon equ 03h ; click on
- keyclof equ 04h ; click off
- keyclr equ 05h ; clear buffer
- keycli equ 06h ; make key click
- keybel equ 07h ; make bell sound
- keyena equ 08h ; enable keyboard
- keydis equ 09h ; disable keyboard
- keyeve equ 0ah ; make keyboard event driven (up/down mode)
- keyasc equ 0bh ; make keyboard scan ascii
- keyiena equ 0ch ; enable interrupt
- keyidis equ 0dh ; disable interrupt
-
- data segment
- extrn taklev:byte, comand:byte, flags:byte
- extrn shkadr:word, stkadr:word, trans:byte, ttyact:byte
- ; system dependent references
- extrn vtmacname:word, vtmaclen:word ; external macro, in msyibm
- extrn vtemu:byte ; emulator data
-
- ;;; System Independent local storage
-
- tranbuf db 132 dup (?) ; 132 byte translator work buffer
- crlf db cr,lf,'$'
- dfhelp1 db cr,lf,' Enter key',27h,'s identification as a character',cr,lf
- db ' or as its numerical equivalent \{b##} of ascii',cr,lf
- db ' or as its scan code \{b##}'
- db cr,lf,' or as SCAN followed by its scan code',cr,lf
- db ' where b is O for octal, X for hex, or D for decimal'
- db ' (default).',cr,lf,' Braces {} are optional.'
- db cr,lf,' Follow the identification with the new definition.'
- db cr,lf,' or CLEAR to restore initial key settings'
- db cr,lf,' or ON (def) to use SCAN CODES, OFF to use ASCII.$';Z100
- dfaskky db cr,lf,' Push key to be defined: $'
- dfaskdf db ' Enter new definition: ',0 ; asciiz for prompt
- verbbad db cr,lf,' No such verb',cr,lf,'$'
- strbad db cr,lf,' Not enough space for new string',cr,lf,'$'
- keyfull db cr,lf,' No more space to define keys',cr,lf,'$'
- dfkoops db cr,lf,' Oops! That is Kermit',27h,'s Escape Char.'
- db ' Translation is not permitted.',cr,lf,'$'
- shkmsg1 db cr,lf,'Push key to be shown (? shows all): $'
- shkmsg2 db ' decimal is defined as',cr,lf,'$'
- shkmsg3 db cr,lf,'... more, press a key to continue ...$'
- kwarnmsg db cr,lf,' Notice: this form of Set Key is obsolete$'
-
- ascmsg db ' Ascii char: $'
- scanmsg db ' Scan Code $'
- strngmsg db ' String: $'
- verbmsg db ' Verb: $'
- noxmsg db ' Self, no translation.$'
- fremsg db cr,lf,' Free space: $'
- kyfrdef db ' key and $'
- stfrdef db ' string definitions, $'
- stfrspc db ' string characters.',cr,lf,'$'
- ; translation tables
- keylist dw maxkeys dup (0) ; 16 bit keycodes, paralled by dirlist
- dirlist dw maxkeys dup (0) ; director {v+s} + {index | new char}
- sptable dw maxstng dup (0) ; list of asciiz string offsets
- stbuf dw stbuflen dup (0) ; buffer for strings
- strmax dw stbuf ; first free byte in stbuf
- listptr dw ? ; item number for keylist and dirlist
- nkeys dw 0 ; number of actively defined keys
- keycode dw ? ; ascii/scan code for key
- kbtemp dw ? ; scratch storage for translator
- brace db ? ; brace detected flag byte
- oldform db 0 ; old form Set Key, if non-zero
- verblen dw ? ; length of user's verb (work temp)
- kwcnt dw ? ; number of keywords (work temp)
- msutake db ? ; if being run from take file or not
- stringcnt dw 0 ; qty of string chars to be processed
- stringptr dw 0 ; address of next string char
- twelve dw 11d ; sorry, one less than that for Z-100
- dosflg db 0
- ;;; End System Independent Data Area
-
- ;;; System Dependent Data Area
- dosflg1 db 0 ; scan codes enabled/key extension disabled=1
- nrcptr dw 0 ; pointer to code page to NRC table
- latinptr dw 0 ; pointer to code page to Latin1 table
- DECmnptr dw 0 ; pointer to code page to DEC-MCS table
- ; edit dfhelp2 to include nice list of verbs for this system.
- dfhelp2 db cr,lf,' Enter either \Kverb for a Kermit action verb',cr,lf
- db ' or a replacement string (single byte binary numbers are'
- db ' \{b##})',cr,lf,' or push Return to undefine a key, ^C to'
- db ' retain current definition.'
- db cr,lf,' Braces {} are optional, and strings maybe enclosed in'
- db ' them.',cr,lf,' Strings may not begin with the character'
- db ' combinations of \k or \{k',cr,lf
- db ' (start with a { brace instead).',cr,lf,lf
- db ' Verbs are as follows. VT52 keys (arrows and keypad):',cr,lf
- db ' uparr, dnarr, lfarr, rtarr, kpminus, kpcoma, kpdot, kpenter,'
- db cr,lf
- db ' Gold (same as PF1), PF1, PF2, PF3, PF4, kp0, ... kp9'
- db cr,lf,' Z-100/Heath-19 function and special key actions:',cr,lf
- db ' F0, ... F12, SF0, ... SF11, i_chr, d_chr, i_line, d_line'
- db cr,lf,' Kermit screen control and actions:',cr,lf
- db ' upscn, dnscn, homscn, endscn, upone, dnone, prtscn, dump,'
- db cr,lf
- db ' scroll, logoff, logon, modeline, break, lbreak,'
- db cr,lf
- ; db ' logoff, logon, termtype, reset, modeline, break,'
- ; db ' lbreak, nethold,'
- ; db cr,lf
- db ' hangup, null (send one), DOS, help,'
- db ' status, exit'
- db cr,lf,'$'
-
- ; Z-100 scan codes, used for setting keycode shift and control flags
- ; column 1 unshift, column 2 shift, column 3 control, column 4
- ; shift-control
- z10keyl equ this byte
- db 30h,29h,30h,29h ; 0,)
- db 31h,21h,31h,21h ; 1,!
- db 32h,40h,32h,00h ; 2,@
- db 33h,23h,33h,23h ; 3,#
- db 34h,24h,34h,24h ; 4,$
- db 35h,25h,35h,25h ; 5,%
- db 36h,5eh,36h,1eh ; 6,^
- db 37h,26h,37h,26h ; 7,&
- db 38h,2ah,38h,2ah ; 8,*
- db 39h,28h,39h,28h ; 9,(
- db 61h,41h,01h,01h ; a,A
- db 62h,42h,02h,02h ; b,B
- db 63h,43h,03h,03h ; c,C
- db 64h,44h,04h,04h ; d,D
- db 65h,45h,05h,05h ; e,E
- db 66h,46h,06h,06h ; f,F
- db 67h,47h,07h,07h ; g,G
- db 68h,48h,08h,08h ; h,H
- db 69h,49h,09h,09h ; i,I
- db 6ah,4ah,0ah,0ah ; j,J
- db 6bh,4bh,0bh,0bh ; k,K
- db 6ch,4ch,0ch,0ch ; l,L
- db 6dh,4dh,0dh,0dh ; m,M
- db 6eh,4eh,0eh,0eh ; n,N
- db 6fh,4fh,0fh,0fh ; o,O
- db 70h,50h,10h,10h ; p,P
- db 71h,51h,11h,11h ; q,Q
- db 72h,52h,12h,12h ; r,R
- db 73h,53h,13h,13h ; s,S
- db 74h,54h,14h,14h ; t,T
- db 75h,55h,15h,15h ; u,U
- db 76h,56h,16h,16h ; v,V
- db 77h,57h,17h,17h ; w,W
- db 78h,58h,18h,18h ; x,X
- db 79h,59h,19h,19h ; y,Y
- db 7ah,5ah,1ah,1ah ; z,Z
- db 08h,08h,08h,08h ; BACKSPACE
- db 09h,09h,09h,09h ; TAB
- db 0ah,0ah,0ah,0ah ; LINE FEED
- db 0dh,0dh,0dh,0dh ; RETURN
- db 1bh,1bh,1bh,1bh ; ESC
- db 20h,20h,20h,20h ; SPACE
- db 27h,22h,27h,22h ; ',"
- db 2ch,3ch,2ch,3ch ; ,,<
- db 2dh,5fh,2dh,1fh ; -,_
- db 2eh,3eh,2eh,3eh ; .,>
- db 2fh,3fh,2fh,3fh ; /,?
- db 3bh,3ah,3bh,3ah ; ;,:
- db 3dh,2bh,3dh,2bh ; =,+
- db 5bh,7bh,1bh,7bh ; [,{
- db 5ch,7ch,1ch,7ch ; \,|
- db 5dh,7dh,1dh,7dh ; ],}
- db 60h,7eh,60h,7eh ; `,~
- db 7fh,7fh,7fh,7fh ; DELETE
- db 8dh,0cdh,8dh,0cdh ; ENTER
- db 95h,0d5h,95h,0c5h ; HELP
- db 96h,0d6h,96h,0d6h ; F0
- db 97h,0d7h,97h,0d7h ; F1
- db 98h,0d8h,98h,0d8h ; F2
- db 99h,0d9h,99h,0d9h ; F3
- db 9ah,0dah,9ah,0dah ; F4
- db 9bh,0dbh,9bh,0dbh ; F5
- db 9ch,0dch,9ch,0dch ; F6
- db 9dh,0ddh,9dh,0ddh ; F7
- db 9eh,0deh,9eh,0deh ; F8
- db 9fh,0dfh,9fh,0dfh ; F9
- db 0a0h,0e0h,0a0h,0e0h ; F10
- db 0a1h,0e1h,0a1h,0e1h ; F11
- db 0a2h,0e2h,0a2h,0e2h ; F12
- db 0a3h,0e3h,0a3h,0e3h ; I CHR, D CHR
- db 0a4h,0e4h,0a4h,0e4h ; I LINE, D LINE
- db 0a5h,0e5h,0a5h,0e5h ; UP ARROW
- db 0a6h,0e6h,0a6h,0e6h ; DOWN ARROW
- db 0a7h,0e7h,0a7h,0e7h ; RIGHT ARROW
- db 0a8h,0e8h,0a8h,0e8h ; LEFT ARROW
- db 0a9h,0e9h,0a9h,0e9h ; HOME
- db 0aah,0eah,0aah,0eah ; BREAK
- db 0adh,0edh,0adh,0edh ; keypad -
- db 0aeh,0eeh,0aeh,0eeh ; keypad .
- db 0b0h,0f0h,0b0h,0f0h ; keypad 0
- db 0b1h,0f1h,0b1h,0f1h ; keypad 1
- db 0b2h,0f2h,0b2h,0f2h ; keypad 2
- db 0b3h,0f3h,0b3h,0f3h ; keypad 3
- db 0b4h,0f4h,0b4h,0f4h ; keypad 4
- db 0b5h,0f5h,0b5h,0f5h ; keypad 5
- db 0b6h,0f6h,0b6h,0f6h ; keypad 6
- db 0b7h,0f7h,0b7h,0f7h ; keypad 7
- db 0b8h,0f8h,0b8h,0f8h ; keypad 8
- db 0b9h,0f9h,0b9h,0f9h ; keypad 9
- lz10keyl equ $ - z10keyl
-
- kverbs db 72 ; number of table entries below
- mkeyw 'uparr',uparrw ; independent of ordering and case!
- mkeyw 'dnarr',dnarrw ; mkeyw 'name',procedure entry point
- mkeyw 'lfarr',lfarr
- mkeyw 'rtarr',rtarr
- mkeyw 'Gold',pf1
- mkeyw 'PF1',pf1
- mkeyw 'PF2',pf2
- mkeyw 'PF3',pf3
- mkeyw 'PF4',pf4
- mkeyw 'KP0',kp0
- mkeyw 'KP1',kp1
- mkeyw 'KP2',kp2
- mkeyw 'KP3',kp3
- mkeyw 'KP4',kp4
- mkeyw 'KP5',kp5
- mkeyw 'KP6',kp6
- mkeyw 'KP7',kp7
- mkeyw 'KP8',kp8
- mkeyw 'KP9',kp9
- mkeyw 'kpminus',kpminus
- mkeyw 'kpcoma',kpcoma
- mkeyw 'kpenter',kpenter
- mkeyw 'kpdot',kpdot
- mkeyw 'F0',f0
- mkeyw 'F1',f1
- mkeyw 'F2',f2
- mkeyw 'F3',f3
- mkeyw 'F4',f4
- mkeyw 'F5',f5
- mkeyw 'F6',f6
- mkeyw 'F7',f7
- mkeyw 'F8',f8
- mkeyw 'F9',f9
- mkeyw 'F10',f10
- mkeyw 'F11',f11
- mkeyw 'F12',f12
- mkeyw 'SF0',sf0
- mkeyw 'SF1',sf1
- mkeyw 'SF2',sf2
- mkeyw 'SF3',sf3
- mkeyw 'SF4',sf4
- mkeyw 'SF5',sf5
- mkeyw 'SF6',sf6
- mkeyw 'SF7',sf7
- mkeyw 'SF8',sf8
- mkeyw 'SF9',sf9
- mkeyw 'SF10',sf10
- mkeyw 'SF11',sf11
- mkeyw 'i_chr',i_chr
- mkeyw 'd_chr',d_chr
- mkeyw 'i_line',i_line
- mkeyw 'd_line',d_line
- comment @
- mkeyw 'decF6',decf6
- mkeyw 'decF7',decf7
- mkeyw 'decF8',decf8
- mkeyw 'decF9',decf9
- mkeyw 'decF10',decf10
- mkeyw 'decF11',decf11
- mkeyw 'decF12',decf12
- mkeyw 'decF13',decf13
- mkeyw 'decF14',decf14
- mkeyw 'decHelp',dechelp
- mkeyw 'decDo',decdo
- mkeyw 'decF17',decf17
- mkeyw 'decF18',decf18
- mkeyw 'decF19',decf19
- mkeyw 'decF20',decf20
- mkeyw 'decFind',decfind
- mkeyw 'decInsert',decinsert
- mkeyw 'decRemove',decremove
- mkeyw 'decSelect',decselect
- mkeyw 'decPrev',decprev
- mkeyw 'decNext',decnext
- mkeyw 'termtype',vtans52
- mkeyw 'reset',vtinit
- end comment @
- mkeyw 'dnscn',dnwpg
- mkeyw 'upscn',upwpg
- mkeyw 'endscn',endwnd
- mkeyw 'upone',upone
- mkeyw 'dnone',dnone
- mkeyw 'prtscn',trnprs
- mkeyw 'dump',dmpscn
- mkeyw 'homscn',homwnd
- mkeyw 'modeline',trnmod
- mkeyw 'break',sendbr
- mkeyw 'lbreak',sendbl
- mkeyw 'hangup',chang
- mkeyw 'null',snull
- mkeyw 'logon',klogon
- mkeyw 'logoff',klogof
- mkeyw 'DOS',cdos
- mkeyw 'help',cquery
- mkeyw 'status',cstatus
- mkeyw 'exit',cquit
- mkeyw 'scroll',scroll
-
- ; Kermit Z-100 Initialization keypad
- ; data.
- ; PF1 to PF4 are shifted home,
- ; leftarrow, rightarrow and uparrow
- ; first the Z-100 numeric keypad
- kbdinlst equ this byte ; mkeyw 'definition',keycode
- mkeyw '\khomscn',scan+0a9h ; home key
- mkeyw '\klfarr',scan+0a8h ; leftarrow
- mkeyw '\krtarr',scan+0a7h ; rightarrow
- mkeyw '\kuparr',scan+0a5h ; uparrow
- mkeyw '\kkp7',scan+0b7h ; kp7
- mkeyw '\kkp8',scan+0b8h ; kp8
- mkeyw '\kkp9',scan+0b9h ; kp9
- mkeyw '\kdnarr',scan+0a6h ; downarrow
- mkeyw '\kkp4',scan+0b4h ; kp4
- mkeyw '\kkp5',scan+0b5h ; kp5
- mkeyw '\kkp6',scan+0b6h ; kp6
- mkeyw '\kkpminus',scan+0adh ; kp minus
- mkeyw '\kkp1',scan+0b1h ; kp1
- mkeyw '\kkp2',scan+0b2h ; kp2
- mkeyw '\kkp3',scan+0b3h ; kp3
- mkeyw '\kkpenter',scan+08dh ; Enter key
- mkeyw '\kkp0',scan+0b0h ; kp0
- mkeyw '\kkpdot',scan+0aeh ; kp dot
- mkeyw '\kgold',scan+shift+0e9h; shifted home key => VT100 gold
- mkeyw '\kpf2',scan+shift+0e8h ; shifted left arrow => VT100 PF2
- mkeyw '\kpf3',scan+shift+0e7h ; shifted right arrow => VT100 PF3
- mkeyw '\kpf4',scan+shift+0e5h ; shifted up arrow => VT100 PF4
- mkeyw '\kd_chr',scan+shift+0f7h ; shifted kp7
- mkeyw '\kuparr',scan+shift+0f8h ; shifted kp8
- mkeyw '\ki_chr',scan+shift+0f9h ; shifted kp9
- mkeyw '\kkpminus',scan+shift+0e6h ; shifted down arrow => VT100 minus
- mkeyw '\klfarr',scan+shift+0f4h ; shifted kp4
- mkeyw '\khomscn',scan+shift+0f5h ; shifted kp5
- mkeyw '\krtarr',scan+shift+0f6h ; shifted kp6
- mkeyw '\kkpcoma',scan+shift+0edh ; shifted kp minus => VT100 comma
- mkeyw '\ki_line',scan+shift+0f1h ; shifted kp1
- mkeyw '\kdnarr',scan+shift+0f2h ; shifted kp2
- mkeyw '\kd_line',scan+shift+0f3h ; shifted kp3
- mkeyw '\x0d',scan+shift+0cdh ; shifted enter
- mkeyw '0',scan+shift+0f0h ; shifted kp0
- mkeyw '.',scan+shift+0eeh ; shifted kp dot
- ; Some function keys
- ; VT100 function keys
- mkeyw '\kf0',scan+096h ; F0
- mkeyw '\kf1',scan+097h ; F1
- mkeyw '\kf2',scan+098h ; F2
- mkeyw '\kf3',scan+099h ; F3
- mkeyw '\kf4',scan+09ah ; F4
- mkeyw '\kf5',scan+09bh ; F5
- mkeyw '\kf6',scan+09ch ; F6
- mkeyw '\kf7',scan+09dh ; F7
- mkeyw '\kf8',scan+09eh ; F8
- mkeyw '\kf9',scan+09fh ; F9
- mkeyw '\kf10',scan+0a0h ; F10
- mkeyw '\kscroll',scan+0a1h ; F11 Recover last screen
- mkeyw '\kprtscn',scan+0a2h ; F12 Kermit toggle prn scrn
- mkeyw '\ksf0',scan+shift+0d6h ; SF0
- mkeyw '\ksf1',scan+shift+0d7h ; SF1
- mkeyw '\ksf2',scan+shift+0d8h ; SF2
- mkeyw '\ksf3',scan+shift+0d9h ; SF3
- mkeyw '\ksf4',scan+shift+0dah ; SF4
- mkeyw '\ksf5',scan+shift+0dbh ; SF5
- mkeyw '\ksf6',scan+shift+0dch ; SF6
- mkeyw '\ksf7',scan+shift+0ddh ; SF7
- mkeyw '\ksf8',scan+shift+0deh ; SF8
- mkeyw '\ksf9',scan+shift+0dfh ; SF9
- mkeyw '\ksf10',scan+shift+0e0h; SF10
- mkeyw '\kdump',scan+shift+0e1h; SF11 Kermit Dump Screen
- ; SF12 not available, used by DOS prtscr
- ; Some special keys
- mkeyw '\klbreak',scan+shift+0eah; Shift-Break sends a Long Break
- mkeyw '\khelp',scan+095h ; Connect mode drop down menu
- mkeyw '\kstatus',scan+shift+0d5h; Display Status
- ; mkeyw '\kdnone',scan+0a3h ; I CHR scrolls down 1 line
- ; mkeyw '\kupone',scan+shift+0e3h ; D CHR scrolls up 1 line
- ; mkeyw '\kdnscn',scan+0a4h ; I LINE scrolls down 1 page
- ; mkeyw '\kupscn',scan+shift+0e4h ; D LINE scrolls up 1 page
- mkeyw '\ki_chr',scan+0a3h ; I CHR sends ESC @ or ESC O
- mkeyw '\kd_chr',scan+shift+0e3h ; D CHR sends ESC N
- mkeyw '\ki_line',scan+0a4h ; I LINE sends ESC L
- mkeyw '\kd_line',scan+shift+0e4h; D LINE sends ESC M
- dw 0 ; end of table marker
-
- kbcodes dw 80h ; keyboard read codes, 80h=not inited
-
- data ends
-
- ; Documentation
- ;Translating a key:
- ; The translator is called to obtain keyboard input; it sends characters to
- ; the serial port through standard controlled echo procedures or invokes
- ; named procedures. It returns carry clear when its operation is completed
- ; for normal actions and carry set when Connect mode must be exited. When
- ; Connect mode is exited the just read char should be passed in Kbdflg
- ; to msster.asm for invoking actions such as Status, send a break,
- ; quit connect mode; system dependent procedure Term is responsible for this.
- ;
- ; Principal procedures are -
- ; msuinit Initializes keyboard translator in this file when
- ; Kermit first begins. Installs dfkey and shkey as the
- ; procedures used for Set Key and Show Key. Sys Indep.
- ; Called from msx or msy init procs. System Independent.
- ; keybd Performs the translation, outputs chars to the serial
- ; port or invokes a Kermit action routine. Sys Indep.
- ; dfkey Defines a key's translation. Reads command line
- ; via Kermit's command parser comnd. System Independent.
- ; shkey Shows translation of a key. Requests user to push
- ; selected key. System Independent.
- ;
- ; kbdinit optional. Initializes the translation tables when
- ; Kermit starts up. Called by msuinit. System Dependent.
- ; getkey Performs the keyboard read and returns results in
- ; a standardized system independent format. Sys Depend.
- ; postkey called by active translator after obtaining a keycode.
- ; Used to provide extra local actions (keyclick) only
- ; in Connect mode (not during Set/Show key commands).
- ; Called by keybd. System dependent.
- ; Supporting system independent procedures are -
- ; shkfre (show string free space), tstkeyw (finds user's keyword in the verb
- ; table), insertst (insert string in buffer), remstr (delete string in buffer).
- ;
- ; System dependent procedure Getkey reads a keycode (usually via a Bios
- ; call). On IBM compatible machines this yields <ah=scan code, al=ascii>
- ; for ordinary keys, or <ah=scan code, al=0> for special keys such as F1,
- ; or <ah=0, al=###> when Alt### is used.
- ; For any system, the canonical output form is the key's code in Keycode.
- ; Place the ascii code (or scan code if none) in byte Keycode and ancillary
- ; info (shift states plus marker bit for scan codes) in byte Keycode + 1.
- ;
- ; Procedure Keybd calls Getkey for the Keycode, checks list of translatable
- ; keys Keylist, and then either sends an ascii string (one or more characters)
- ; or invokes a Kermit action verb. List Dirlist indicates what kind of
- ; translation to do. Keybd is system independent but may contain system
- ; dependent special actions such as echoing keyclicks. Keybd calls system
- ; dependent procedure Postkey just after calling getkey so local actions
- ; such as keyclicks can be activated only during Connect mode operations.
- ;
- ; Keylist is a packed but unordered list of 16 bit keycodes which need
- ; translation. The lower order byte holds a key code (ascii char or scan code)
- ; while the high byte holds a scan code marker bit (0 if ascii code in low
- ; byte) plus any ancillary keyboard information such as Control/Shift/Alt/Meta
- ; keys being held down; these are of use in Show Key presentations.
- ; Dirlist parallels Keylist to provide the kind of translation, verb or
- ; string, in the two highest bits with the other bits holding either
- ; a single new replacement character or the item number in lists of verbs
- ; or strings. If neither verb nor strng type bits are set in a dirlist
- ; word then the translation is a single new character held in the lower
- ; eight bits of that dirlist word.
- ;
- ; The number of key translations is assembly constant Maxkeys (def 128).
- ; The maximum number of strings is assembly constant Maxstngs (def 64).
- ; The maximum number of verbs is 256 and is set by building table Kverbs.
- ;
- ; For verbs, use the Item number from the Director table Dirlist to select
- ; a procedure offset from the structured list Kverbs and jump to that offset.
- ; Most verb procedures return carry clear to stay within Connect mode.
- ; Verbs requiring exiting Connect mode return carry set and may set byte
- ; Kbdflg to a char code which will be read by msster.asm for activating a
- ; transient Kermit action such as send a break (Kbdflg = 'b').
- ; Kbdflg is stored in msster.asm (as zero initially, meaning ignore it).
- ; Action verb procedures are normally located in a system dependent file.
- ;
- ; For multi-char strings, use Item number from Director table Dirlist to
- ; select a pointer to a string. The list of string pointers is Sptable
- ; (string pointer table) which holds the offset in the data segment of the
- ; strings stored in buffer Stbuf. In stbuf strings are held as: one byte of
- ; length of following text and then the text itself (permits embedded nulls).
- ; Use Chrout to send each string character, and finally return from Keybd
- ; with carry clear.
- ;
- ; For single character replacements obtain the new character from the lower
- ; order byte of Director table Dirlist. If the character is Kermit's present
- ; escape character return from Keybd carry set to leave connect mode.
- ; Otherwise, send the character via Chrout and return from Keybd carry clear.
-
- ; Keylist table format:
- ; 7 bits 1 bit 8 bits
- ; +----------+----+------------+ scan bit = 1 if key's code is non-ascii
- ; | aux info |scan| key's code | aux info = system dependent, used only to
- ; +----------+----+------------+ help identify key
- ;
- ; Dirlist table format v s meaning
- ; 1 1 14 bits 0 0 copy out one byte translation
- ; +---+---+--------------------+ 1 0 copy out multi-char string number Item
- ; | v | s | item # or new char | 0 1 do action verb number Item
- ; +---+---+--------------------+ 1 1 (not used)
- ;
- ; Table kverbs is organized by macro mkeyw as -
- ; kverbs db number of table entries
- ; (each entry is in the form below:)
- ; db number of bytes in verbname
- ; db 'verbname' variable length
- ; db '$' for printing
- ; dw value offset of procedure
- ;
- ;
- ; Dfkey defines a key to be itself (undefines it) or a single replacement
- ; character or a character string or a Kermit action verb. Dfkey requires
- ; a command line so that it may be invoked by Take files but can be forced
- ; to prompt an interactive user to push a key. Syntax is discussed below.
- ; Note that redefined keys have their old definitions cleared so that
- ; old string space is reclaimed automatically.
- ;
- ; Shkey displays a key's definition and the user is asked to push the
- ; selected key. The free space for strings is always shown afterward. See
- ; below for syntax.
- ;
- ; Kbdinit is an optional routine called when Kermit starts up. It fills in
- ; the translation tables with desirable default values to save having to
- ; use long mskermit.ini files. The default values are stored in a structured
- ; table similar to (but not the same as) Dfkey's command lines; the keycode
- ; values are preset by hand to 16 bit numbers.
-
- ;Defining a key:
- ; Command is SET KEY <key ident><whitespace><definition>
- ;
- ; <key ident> is
- ; a single ordinary ascii char or
- ; the numerical equivalent of an ascii char or
- ; a Scan Code written as a number or
- ; keyword SCAN followed by a number.
- ; ? Displays help message.
- ; Numbers and Binary codes are of the form
- ; \123 a decimal number
- ; \o456 an octal number base letters o, d, x can be
- ; \d213 a decimal number upper or lower case
- ; \x0d a hex number
- ; \{b###} braces around above material following slash.
- ;
- ; <whitespace> is one or more spaces and or tabs.
- ;
- ; <definition> is
- ; missing altogether which "undefines" a key.
- ; \Kverb for a Kermit action verb; upper or lower case K is ok
- ; \{Kverb} ditto. Verb is the name of an action verb.
- ; text a string with allowed embedded whitespace and embedded
- ; binary chars as above. This kind of string may not
- ; commence with sequences \K or \{K; use braces below.
- ; {text} string confined to material within but excluding
- ; the braces. Note, where the number of opening braces
- ; exceeds the number of closing braces the end of line
- ; terminates the string: {ab{}{{c}d ==> ab{}{{c}d
- ; but {ab}{{c}d ==> ab.
- ; ? Displays help message and lists all action verbs.
- ;
- ; If Set Key is given interactively, as opposed to within a Take
- ; file, the system will prompt for inputs if none is on the command
- ; line. The response to Push key to be defined cannot be edited.
- ;
- ; Text which reduces to a single replacement character is put into a
- ; table separate from the multi-character strings (maxstng of these).
- ; A key may be translated into any single 8 bit code.
- ;
- ; Comments can follow a Kermit action verb or a braced string; no
- ; semicolon is required since all are stripped out by the Take file
- ; reader before the defining text is seen by SET KEY.
- ;
- ; The current Kermit escape character cannot be translated without
- ; subtrafuge.
- ;
- ; Examples:
- ; Set Key q z
- ; makes key q send character z
- ; Set Key \7 \27[0m
- ; makes key Control G send the four byte
- ; string ESC [ 0 m
- ; Set Key q
- ; undefines key q so it sends itself (q) again.
- ; Set Key \2349 \kexit
- ; defines IBM Alt-X to invoke the leave connect
- ; mode verb "exit" (Kermit's escape-char ^] C).
- ; Set Key \x0c Login \{x0d}myname\{x0d}mypass\x0d
- ; defines Control L to send the string
- ; Login <cr>myname<cr>mypass<cr>
- ;
- ; Alternative Set Key syntax for backward compatibility with previous versions
- ; The same forms as above except the key identification number must
- ; be decimal and must Not have a leading backslash. Example:
- ; Set Key Scan 59 This is the F1 key
- ;
- ; If the definition is omitted it may be placed on the following line;
- ; if that line is also empty the key is undefined (defined as Self).
- ; A warning message about obsolete syntax will be given followed by
- ; the key's modern numerical value and new definition. Only "special"
- ; keys (those not producing ascii codes) are compatible with this
- ; translator.
- ;
- ;Showing a key:
- ; Command is SHOW KEY <cr>
- ; System prompts user to press a key and shows the definition plus the
- ; free space for strings. Query response results in showing all definitions.
- ; End Documentation
-
- code segment
- ; system independent external items
- extrn comnd:near, prompt:near, iseof:near ; in msscmd
- extrn strlen:near, prtscr:near ; in mssfil
- extrn cnvlin:near, katoi:near, decout:near ; in msster
- ; system dependent external items
- extrn beep:near, ena_scan:near, dis_scan:near ; in msxz10
- extrn vclick:near ; in msxz10
- ; these are system dependent action verbs, in msxibm & msyibm
- extrn f0:near, f1:near, f2:near, f3:near, f4:near, f5:near, f6:near
- extrn f7:near, f8:near, f9:near, f10:near, f11:near, f12:near
- extrn sf0:near, sf1:near, sf2:near, sf3:near, sf4:near, sf5:near
- extrn sf6:near, sf7:near, sf8:near, sf9:near, sf10:near, sf11:near
- extrn i_chr:near, d_chr:near, i_line:near, d_line:near
- extrn uparrw:near, dnarrw:near, rtarr:near, lfarr:near
- extrn pf1:near, pf2:near, pf3:near, pf4:near, kp0:near, kp1:near
- extrn kp2:near, kp3:near, kp4:near, kp5:near, kp6:near, kp7:near
- extrn kp8:near, kp9:near, kpminus:near, kpcoma:near, kpenter:near
- extrn kpdot:near, dnwpg:near, upwpg:near, scroll:near
- comment @
- extrn kpdot:near, decf6:near, decf7:near, decf8:near, decf9:near
- extrn decf10:near, decf11:near, decf12:near, decf13:near
- extrn decf14:near, dechelp:near, decdo:near, decf17:near
- extrn decf18:near, decf19:near, decf20:near, udkclear:near
- extrn decfind:near, decinsert:near, decremove:near
- extrn decselect:near, decprev:near, decnext:near
- extrn chrout:near, cstatus:near, cquit:near, cquery:near
- extrn vtans52:near, vtinit:near, dnwpg:near, upwpg:near
- end comment @
- extrn endwnd:near, homwnd:near, upone:near, dnone:near, trnprs:near
- extrn chang:near, klogon:near, klogof:near
- extrn trnmod:near, sendbr:near, sendbl:near, dmpscn:near, snull:near
- extrn cplatin:near, nrc2cp:near
- extrn cpdecsg:near, cdos:near, cquery:near, cstatus:near
- extrn chrout:near, cquit:near, udkclear:near, extmacro:near
- assume cs:code, ds:data, es:data
-
- ; Begin system independent Keyboard Translator code
-
- ; MSUINIT performs Kermit startup initialization for this file.
- ; Note, shkadr and stkadr are pointers tested by Set/Show Key calls. If they
- ; are not initialized here then the older Set/Show Key procedures are called.
- MSUINIT PROC NEAR ; call from msx/msy init code
- call kbdinit ; optional: init translator tables
- mov shkadr,offset shkey ; declare keyboard translator present
- mov stkadr,offset dfkey ; via Show and Set Key proc addresses
- ret
- MSUINIT ENDP
-
- ; Call Keybd to read a keyboard char (just returns carry clear if none) and
- ; 1) send the replacement string (or original char if not translated)
- ; out the serial port, or
- ; 2) execute a Kermit action verb.
- ; Returns carry set if Connect mode is to be exited, else carry clear.
- ; Modifies registers ax and bx.
- KEYBD PROC NEAR ; active translator
- mov ttyact,1 ; doing single char output
- cmp stringcnt,0 ; any leftover string chars?
- je keybd0 ; e = no
- jmp keyst2 ; yes, finish string
- keybd0: call getkey ; read keyboard
- jnc keybd1 ; nc = data available
- jmp keybdx ; else just return carry clear
- keybd1: call postkey ; call system dependent post processor
- cmp nkeys,0 ; is number of keys defined = 0?
- jz keybd3 ; z = none defined
- push di ; search keylist for this keycode
- push cx ; save some registers
- push es
- mov di,offset keylist ; list of defined keycode words
- mov ax,keycode ; present keycode
- mov cx,nkeys ; number of words to examine
- push ds
- pop es ; make es:di point to data segment
- cld
- repne scasw ; find keycode in list
- pop es ; restore regs
- pop cx
- je keybd1b ; e = found, work with present di
- pop di ; restore original di
- test keycode,scan ; is this a scan code?
- jz keybd3 ; z = no, it's ascii, use al as char
- call beep ; say key is a dead one
- clc
- ret ; and exit with no action
-
- keybd1b:sub di,2 ; correct for auto increment
- sub di,offset keylist ; subtract start of list ==> listptr
- mov ax,dirlist[di] ; ax = contents of director word
- pop di ; restore original di
- ; dispatch on Director code
- test ax,verb ; verb only?
- jnz keyvb ; e = yes
- test ax,strng ; multi-char string only?
- jnz keyst ; e = yes, else single char & no xlat.
- ;
- ; do single CHAR output (char in al)
- keybd3: cmp al,trans.escchr ; Kermit's escape char?
- je keybd3a ; e = yes, handle separately
- call xltkey ; do character set translation
- call chrout ; transmit the char
- clc ; return success
- ret
- keybd3a:stc ; set carry for jump to Quit
- ret
-
- keyvb: and ax,not(verb+strng) ; VERB (ax=index, remove type bits)
- mov bx,offset kverbs ; start of verb table
- cmp al,byte ptr [bx] ; index > number of entries?
- jae keybdx ; ae = illegal, indices start at 0
- inc bx ; bx points to first entry
- push cx ; save reg
- mov cx,ax ; save the index in cx
- inc cx ; counter, indices start at 0
- keyvb1: mov ax,[bx] ; cnt value
- add ax,4 ; skip text and value word
- add bx,ax ; look at next slot
- loop keyvb1 ; walk to correct slot
- sub bx,2 ; backup to value field
- pop cx ; restore reg
- mov bx,[bx] ; get value field of this slot
- or bx,bx ; jump address defined?
- jz keybdx ; z = no, skip the action
- jmp bx ; perform the function
-
- keyst: and ax,not(verb+strng) ; STRING (ax=index, remove type bits)
- shl ax,1 ; convert to word index
- push si ; save working reg
- mov si,ax ; word subscript in table
- mov si,sptable[si] ; memory offset of selected string
- xor cx,cx ; init string length to null
- or si,si ; is there a string pointer present?
- jz keyst1 ; z = no, skip operation
- cld ; scan forward
- mov cx,[si] ; get string length
- add si,2
- keyst1: mov stringcnt,cx
- mov stringptr,si
- pop si
- jcxz keybdx ; z = null length
-
- keyst2: push si
- mov si,stringptr ; pointer to next string char
- cld
- lodsb ; get new string char into al
- pop si
- dec stringcnt ; string chars remaining
- inc stringptr
- call keysv ; scan for embedded verbs
- jc keyst4 ; c = not found, al has string char
- jmp bx ; perform the verb (bx = address)
- keyst4: cmp stringcnt,0 ; end of the string?
- jne keyst5 ; ne = no
- mov ttyact,0 ; pretend not single char output
- keyst5: jmp chrout ; send out the char in al
-
- keybdx: clc ; return success (nothing to do)
- ret
- KEYBD ENDP
-
- ; Scan for keyboard verbs embedded in outgoing string. If found update
- ; string pointer and count to just beyond the verb and return action routine
- ; address in bx with carry clear. If failure return carry set and no change.
-
- keysv proc near
- push ax
- push si
- push di
- cmp al,'\' ; escape?
- jne keysv7 ; ne = no
- mov cx,stringcnt ; chars remaining
- mov si,stringptr ; address of next char to read
- mov brace,0 ; assume not using braces
- cmp byte ptr [si],braceop ; starts with \{?
- jne keysv1 ; ne = no
- inc si ; skip the opening brace
- dec cx
- mov brace,bracecl ; expect closing brace
- keysv1: cmp byte ptr [si],'K' ; starts with \{K or \K?
- je keysv2 ; e = yes
- cmp byte ptr [si],'k' ; starts as \{k or \k?
- jne keysv7 ; ne = no, then it's a string
- keysv2: inc si ; yes, skip the K too
- dec cx
- mov di,offset tranbuf ; copy verb name to this work buffer
- xor ax,ax
- mov [di],ax ; init the buffer to empty
- keysv3: cld
- jcxz keysv4 ; z = no more string chars
- lodsb ; scan til closing brace or w/s or end
- dec cx
- cmp al,brace ; closing brace?
- je keysv4 ; e = yes
- cmp al,spc ; white space or control char?
- jbe keysv3 ; be = yes
- mov [di],ax ; copy to tranbuf and terminate
- inc di
- jmp short keysv3
- keysv4: push si ; save input reading position
- mov si,offset tranbuf ; where verb starts (needs si)
- call tstkeyw ; find keyword, bx = action routine
- pop si
- jnc keysv4a ; nc = found the verb
- call keysv8 ; invoke EXTMACRO worker for unknown
- jc keysv7 ; carry = no verb to operate upon
- keysv4a:cmp brace,0 ; need to end on a brace?
- je keysv6 ; e = no
- dec si ; break position
- inc cx
- cld
- keysv5: jcxz keysv6 ; z = no more string characters
- lodsb ; read string char
- dec cx
- cmp al,brace ; the brace?
- jne keysv5 ; ne = no, repeat until it is found
- keysv6: mov stringptr,si ; where we finished+1
- mov stringcnt,cx ; new count of remaining chars
- pop di
- pop si ; original si, starting place
- pop ax ; original ax
- clc
- ret
- keysv7: pop di ; verb not found
- pop si
- pop ax
- stc
- ret
- ; Worker. Unknown verb name as string {\kverb} or {\k{verb}}. Use EXTMACRO
- ; procedure (in msyibm typically), point to verb name with vtmacname, length
- ; of it in byte vtmaclen, address of EXTMACRO to BX. Upper case the verb.
- ; Enter with tranbuf holding the verb, asciiz, without \K and braces.
- ; Returns BX set to EXTMACRO proc, vtmacname pointing to verb (uppercased)
- ; and vtmaclen holding the length of verb.
- keysv8: mov bx,offset extmacro ; use this external macro pointer
- mov vtmacname,offset tranbuf; select extmacro procedure address
- mov dx,offset tranbuf ; point to name for extmacro
- push cx
- call strlen ; get its length
- mov vtmaclen,cx ; length for extmacro
- jcxz keysv11 ; z = none
- push si ; convert verb name to upper case
- mov si,dx ; verb, without leading \K stuff
- cld
- keysv9: lodsb ; read a name byte
- cmp al,'a' ; before lower case?
- jb keysv10 ; e = yes
- cmp al,'z' ; above lower case?
- ja keysv10 ; a = yes
- and al,not 20h ; convert to upper case
- mov [si-1],al ; put it back
- keysv10:loop keysv9 ; do all bytes, asciiz
- pop si
- pop cx
- clc ; carry clear = ready to execute
- ret
- keysv11:stc ; carry set = no verb, do nothing
- pop cx
- ret
- keysv endp
-
- ; SET KEY - define a key (procedure dfkey)
- ; SET KEY <key ident><whitespace><new meaning>
- ; Call from Kermit level. Returns as ret if failure or as rskp if success.
- ;
- DFKEY PROC NEAR ; define a key as a verb or a string
- mov keycode,0 ; clear keycode
- mov oldform,0 ; say no old form Set Key yet
- or byte ptr kbcodes,80h ; say kbcodes not-initiated
- mov dx,offset tranbuf ; our work space
- mov word ptr tranbuf,0 ; insert terminator
- mov bx,offset dfhelp1 ; first help message
- mov ah,cmword ; parse a word
- call comnd ; get key code or original ascii char
- mov cl,taklev ; reading from Take file
- mov msutake,cl ; save here
- or ax,ax ; any text given?
- jnz dfkey12 ; nz = yes, so don't consider prompts
- ; interactive key request
- cmp taklev,0 ; in a Take file?
- je dfkey10 ; e = no, prompt for keystroke
- jmp dfkey0 ; else say bad syntax
- dfkey10:mov ah,prstr
- mov dx,offset dfaskky ; ask for key to be pressed
- int dos
- dfkey11:call getkey ; read key ident from keyboard
- jc dfkey11 ; c = no response, wait for keystroke
- mov ah,prstr ; display cr/lf
- mov dx,offset crlf
- int dos
- call shkey0 ; show current definition (in SHKEY)
- jmp dfkey1e ; prompt for and process definition
-
- dfkey12: ; Look for word SCAN and ignore it
- mov dx,word ptr tranbuf ; get first two characters
- or dx,2020h ; map upper to lower case
- cmp dx,'cs' ; first two letters of word "scan"?
- je dfkey ; e = yes, skip the word
- cmp dx,'lc' ; first two letters of word "clear"?
- je dfkey15 ; e = yes, reinit keyboard [2.31]
- cmp dx,'fo' ; first two letters of "off"
- je dfkey13 ; e = yes, use DOS keyboard calls
- cmp dx,'no' ; first two letters of "on"
- je dfkey14 ; e = yes, use standard kbd calls
- cmp ax,1 ; number of characters received
- jbe dfkey12a ; be = stay here
- jmp dfkey1 ; a = more than one, decode
- dfkey12a:mov ah,byte ptr tranbuf ; get the single char
- mov byte ptr keycode,ah ; store as ascii keycode
- jmp dfkey1b ; go get definition
- dfkey13:push dx ; save command letters
- mov ah,cmeol ; get end of line confirmation
- call comnd
- pop dx
- jnc dfkey14 ; nc = success
- ret
- dfkey14:mov al,0ffh ; set DOS keyboard read flag
- cmp dx,'fo' ; first two letters of "off"
- je dfkey14a ; e = yes, use DOS keyboard calls
- xor al,al ; clear DOS keyboard read flag
- cmp dx,'no' ; first two letters of "on"
- je dfkey14a ; e = yes, use standard kbd calls
- mov al,dosflg ; get current flag
- dfkey14a:mov dosflg,al ; store new keyboard flag
- ret
-
-
- dfkey15:mov ah,cmeol
- call comnd ; confirm request before proceeding
- jnc dfkeyc ; nc = success
- ret ; failure
-
- dfkey0: mov dx,offset dfhelp1 ; say bad definition command
- mov ah,prstr
- int dos
- stc ; failure
- ret
-
- dfkeyc: ; CLEAR key defs, restore startup defs
- mov cx,maxkeys ; size of keycode tables
- push es ; save register
- push ds
- pop es ; make es point to data segment
- xor ax,ax ; null, value to be stored
- mov di,offset dirlist ; director table
- cld
- rep stosw ; clear it
- mov cx,maxkeys
- mov di,offset keylist ; keycode table
- rep stosw ; clear it
- mov cx,maxstng
- mov di,offset sptable ; string pointer table
- rep stosw ; clear it
- pop es ; recover register
- mov strmax,offset stbuf ; clear string buffer, free space ptr
- mov stbuf,0 ; first element of buffer
- mov nkeys,0 ; clear number of defined keys
- call msuinit ; restore startup definitions
- clc ; success
- ret
- ; Multi-char key identification
- dfkey1: mov si,offset tranbuf ; point to key ident text
- cmp byte ptr [si],'0' ; is first character numeric?
- jb dfkey1a ; b = no
- cmp byte ptr [si],'9' ; in numbers?
- ja dfkey1a ; a = no
- mov keycode,scan ; setup keycode for scan value
- mov dx,si ; get length of string in cx
- call strlen
- push ds
- pop es ; make es point to data segment
- push si
- add si,cx ; point at string terminator
- mov di,si
- inc di ; place to store string (1 byte later)
- inc cx ; include null terminator
- std ; work backward
- rep movsb ; move string one place later
- cld
- pop si
- mov byte ptr [si],'\' ; make ascii digits into \nnn form
- mov oldform,0ffh ; set old form flag
- mov dx,offset kwarnmsg ; tell user this is old form
- mov ah,prstr
- int dos
- dfkey1a:call katoi ; convert ascii number to binary in ax
- jc dfkey0 ; c = no number converted
- or keycode,ax ; store in keycode
-
- dfkey1b: ; Get Definition proper
- test oldform,0ffh ; old form Set Key active?
- jz dfkey1f ; z = no
- mov bx,offset tranbuf ; get new definition on main cmd line
- mov word ptr [bx],0 ; insert terminator
- mov dx,offset dfhelp2 ; help for definition of key
- mov ah,cmline ; read rest of line into tranbuf
- call comnd ; allow null definitions
- or ax,ax ; char count zero?
- jz dfkey1e ; z = zero, prompt for definition
- jmp dfkey1g ; process definition
-
- dfkey1e:mov ah,prstr
- mov dx,offset crlf
- int dos
- mov dx,offset dfaskdf ; prompt for definition string
- call prompt ; Kermit prompt routine
- mov comand.cmcr,1 ; permit bare carriage returns
- mov comand.cmwhite,1 ; allow leading whitespace
- dfkey1f:mov bx,offset tranbuf ; get new definition
- mov word ptr [bx],0 ; insert terminator
- mov dx,offset dfhelp2 ; help for definition of key
- mov ah,cmline ; read rest of line into tranbuf
- call comnd
- jc dfkey1x ; exit now on ^C from user
- cmp comand.cmcr,0 ; prompting for definition?
- je dfkey1g ; e = no, trim leading whitespace
- mov comand.cmcr,0 ; turn off allowance for bare c/r's
- jmp dfkey2 ; interactive, allow leading whitespace
- dfkey1x:ret ; failure exit
-
- dfkey1g:push ax ; save count
- mov ah,cmeol ; get a confirm
- call comnd
- pop cx ; string length
- jc dfkey1x ; none so declare parse error
-
- dfkey2: ; Examine translation
- mov al,trans.escchr ; current escape char (port dependent)
- cmp al,byte ptr keycode ; is this Kermit's escape char?
- jne dfkey2a ; ne = no
- test keycode,scan ; see if scan code
- jnz dfkey2a ; nz = scan, so not ascii esc char
- mov dx,offset dfkoops ; Oops! msg
- mov ah,prstr ; complain and don't redefine
- int dos
- stc ; failure
- ret
-
- dfkey2a:push di ; get a director code for this key
- push cx
- mov di,offset keylist ; list of keycodes
- mov cx,nkeys ; number currently defined
- mov ax,keycode ; present keycode
- jcxz dfkey2b ; cx = 0 means none defined yet
- cld
- push ds
- pop es
- repne scasw ; is current keycode in the list?
- jne dfkey2b ; ne = not in list
- sub di,2 ; correct for auto increment
- sub di,offset keylist
- mov listptr,di ; list pointer for existing definition
- pop cx
- pop di
- jmp dfkey3 ; go process definition
-
- dfkey2b:pop cx ; key not currently defined so
- pop di ; make a new director entry for it
- mov bx,nkeys ; number of keys previously defined
- cmp bx,maxkeys ; enough space?
- jae dfkey2c ; ae = no, complain
- shl bx,1 ; count words
- mov listptr,bx ; index into word list
- mov ax,keycode ; get key's code
- mov keylist[bx],ax ; store it in list of keycodes
- mov dirlist[bx],0 ; clear the new director entry
- inc nkeys ; new number of keys
- jmp dfkey3 ; go process definition
-
- dfkey2c:mov dx,offset keyfull ; say key space is full already
- mov ah,prstr
- int dos
- stc ; failure
- ret
-
- ; listptr has element number in keylist or dirlist; keycode has key's code.
-
- ; Parse new definition. First look for Kermit verbs as a line beginning
- ; as \K or \{K. Otherwise, consider the line to be a string.
- ; In any case, update the Director table for the new definition.
-
- dfkey3: mov brace,0 ; assume not using braces
- mov si,offset tranbuf ; start of definition text
- cmp byte ptr [si],'\' ; starts with escape char?
- jne dfkey5 ; ne = no, so we have a string
- inc si ; skip the backslash
- cmp byte ptr [si],braceop ; starts with \{?
- jne dfkey3a ; ne = no
- inc si ; skip the opening brace
- mov brace,bracecl ; expect closing brace
- dfkey3a:cmp byte ptr [si],'K' ; starts with \{K or \K?
- je dfkey3b ; e = yes
- cmp byte ptr [si],'k' ; starts as \{k or \k?
- jne dfkey5 ; ne = no, then it's a string
- dfkey3b:inc si ; yes, skip the K too
- ; Kermit action VERBS
- push si ; save verb name start address
- dfkey4: cld
- lodsb ; scan til closing brace or w/s or end
- or al,al ; premature end?
- jz dfkey4b ; z = yes, accept without brace
- cmp al,brace ; closing brace?
- je dfkey4b ; e = yes
- cmp al,spc ; white space or control char?
- ja short dfkey4 ; a = no, so not at end yet
- dfkey4b:mov byte ptr[si-1],0 ; insert null terminator
- pop si ; recover start address
- call tstkeyw ; find keyword, kw # returned in kbtemp
- jc dfkey4d ; c = no keyword found, complain
- call remstr ; clear old string, if string
- mov ax,kbtemp ; save keyword number
- and ax,not(verb+strng) ; clear verb / string field
- or ax,verb ; set verb ident
- mov si,listptr
- mov dirlist[si],ax ; store info in Director table
- jmp dfkey7 ; show results and return success
-
- dfkey4d:mov dx,offset verbbad ; say no such verb
- mov ah,prstr
- int dos
- stc ; failure
- ret
-
- ; Here we are left with the definition string; si points to its start, and
- ; kbtemp holds its length (number of bytes). Null termination. If the string
- ; begins with an opening brace it terminates on a matching closing brace
- ; or the end of line, whichever occurs first. Trailing whitespace removed
- ; before examining braces.
- ; Null length strings mean define key as Self.
- ; STRING definitions
- dfkey5: call remstr ; first, clear old string, if any
- mov si,offset tranbuf ; si=source, di=dest, convert in-place
- mov di,si
- call cnvlin ; convert numbers, cx gets line length
- mov si,offset tranbuf ; provide address of new string
- cmp cx,1 ; just zero or one byte to do?
- jbe dfkey6 ; e = yes, do as a char
- call insertst ; insert new string, returns reg cx.
- jc dfkey5h ; c = could not do insert
- mov si,listptr ; cx has type and string number
- mov dirlist[si],cx ; update Director table from insertst
- jmp dfkey7 ; show results and return success
-
- dfkey5h:mov dx,offset strbad ; display complaint
- mov ah,prstr
- int dos
- stc ; failure
- ret
-
- ; define SINGLE CHAR replacement or CLEAR a key definition.
- ; cx has char count 1 (normal) or 0 (to undefine the key).
- dfkey6: jcxz dfkey6c ; z = cx= 0, clear definition
- mov al,byte ptr [si] ; get first byte from definition
- xor ah,ah ; set the type bits to Char
- mov si,listptr
- mov dirlist[si],ax ; store type and key's new code
- jmp dfkey7 ; return success
-
- dfkey6c:push si ; clear a definition,
- push di ; listptr points to current def
- mov si,listptr ; starting address to clear
- add si,offset dirlist
- mov di,si ; destination
- add si,2 ; source is next word
- mov cx,nkeys ; current number of keys defined
- add cx,cx ; double for listptr being words
- sub cx,listptr ; cx = number of words to move
- shr cx,1 ; convert to actual number of moves
- jcxz dfkey6d ; z = none, just remove last word
- push es
- push ds
- pop es ; make es:di point to data segment
- cld
- push cx ; save cx
- rep movsw ; move down higher list items
- pop cx
- mov si,listptr ; do keylist too, same way
- add si,offset keylist
- mov di,si
- add si,2
- rep movsw
- pop es
- dfkey6d:mov si,nkeys ; clear old highest list element
- shl si,1 ; address words
- mov dirlist[si],0 ; null the element
- mov keylist[si],0 ; null the element
- dec nkeys ; say one less key defined now
- pop di ; restore saved registers
- pop si
-
- dfkey7: mov ah,msutake ; Finish up. In a Take file?
- or ah,taklev ; or even directly
- or ah,ah
- jz dfkey7a ; z = no
- cmp flags.takflg,0 ; echo Take commands?
- je dfkey7b ; e = no
- dfkey7a:mov ah,prstr ; display cr/lf
- mov dx,offset crlf
- int dos
- call shkey0 ; show new definition (in SHKEY)
- call shkfre ; show free string space
- dfkey7b:clc ; return success
- ret
- DFKEY ENDP
-
- ; SHOW KEY <cr> command. Call from Kermit level. Vectored here by SHOW
- ; command. Replaces obsolete procedure in msx---.
- ; Prompts for a key and shows that key's (or all if ? entered) keycode,
- ; definition, and the key definition free space remaining.
-
- SHKEY PROC NEAR ; Show key's definition command
- mov ah,cmeol ; get a confirm
- call comnd ; ignore any additional text
- push bx
- mov dx,offset shkmsg1 ; ask for original key
- mov ah,prstr
- int dos
- or byte ptr kbcodes,80h ; say kbcodes not-initiated
- shky0: call getkey ; read keyboard, output to keycode
- jc shky0 ; wait for a key (c = nothing there)
- cmp byte ptr keycode,'?' ; query for all keys?
- jne shky0a ; ne = no, not a query
- test keycode,scan ; is this a scan code, vs ascii query?
- jz shky0c ; z = no Scan, so it is a query
-
- shky0a: mov ah,prstr ; show single key. Setup display
- mov dx,offset crlf
- int dos
- call shkey0 ; show just one key
- shky0b: call shkfre ; show free string space
- jmp shkeyx ; exit
-
- shky0c: mov cx,nkeys ; Show all keys. nkeys = number defined
- jcxz shky0b ; z = none to show
- mov si,offset keylist ; list of definitions
- push si ; save pointer
- shky1: pop si ; recover pointer
- cld
- lodsw ; get a keycode
- push si ; save pointer
- push cx ; save counter
- mov keycode,ax ; save new keycode
- mov ah,prstr
- mov dx,offset crlf
- int dos
- call shkey0 ; show this keycode
-
- pop cx ; pause between screens, recover cntr
- push cx ; save it again
- dec cx ; number yet to be shown
- jcxz shky1b ; z = have now shown all of them
- mov ax,nkeys ; number of defined keys
- sub ax,cx ; minus number yet to be displayed
- xor dx,dx ; clear extended numerator
- div twelve ; two lines per definition display
- or dx,dx ; remainder zero (12 defs shown)?
- jnz shky1b ; nz = no, not yet so keep going
- mov ah,prstr
- mov dx,offset shkmsg3 ; "push any key to continue" msg
- int dos
- shky1a: mov ah,0bh ; check console, check ^C
- int dos
- cmp flags.cxzflg,'C' ; a ^C?
- je shky1b ; e = yes, quit
- or al,al
- jz shky1a ; z = nothing
- call getkey ; get any key
- jc shky1a ; c = nothing at keyboard yet, wait
- shky1b: pop cx ; resume loop
- cmp flags.cxzflg,'C' ; a ^C?
- je shky1c ; e = yes, quit
- loop shky1
- shky1c: pop si ; clean stack
- call shkfre ; show free string space
- jmp shkeyx ; exit
-
- ; show key worker routine, called from above
- ; SHKEY0 called by DFKEY just above
- SHKEY0: test keycode,scan ; scan code?
- jz shkey1 ; z = no, regular ascii
-
- ; SCAN codes
- mov dx,offset scanmsg ; say Scan Code:
- mov ah,prstr
- int dos
- mov ah,conout
- mov dl,'\' ; add backslash before number
- int dos
- mov ax,keycode ; get key's code again
- call decout ; display 16 bit decimal keycode
- jmp shkey2 ; go get definition
-
- shkey1: mov dx,offset ascmsg ; say ASCII CHAR
- mov ah,prstr
- int dos
- mov dl,byte ptr keycode ; get ascii code (al part of input)
- mov ah,conout
- cmp dl,spc ; control code?
- jae shkey1a ; ae = no
- push dx ; save char
- mov dl,5eh ; show caret first
- int dos
- pop dx
- add dl,'A'-1 ; ascii bias
- shkey1a:cmp dl,del ; DEL?
- jne shkey1b ; ne = no
- mov dl,'D' ; spell out DEL
- int dos
- mov dl,'E'
- int dos
- mov dl,'L'
- shkey1b:int dos
- mov dl,spc ; add a couple of spaces
- int dos
- int dos
- mov dl,'\' ; add backslash before number
- int dos
- mov ax,keycode ; show 16 bit keycode in decimal
- call decout ; and go get definiton
-
- ; Display defintion
- shkey2: mov dx,offset shkmsg2 ; intermediate part of reply
- mov ah,prstr ; " is defined as "
- int dos
- push di ; get a director code for this key
- push cx
- mov di,offset keylist ; list of keycodes
- mov cx,nkeys ; number currently defined
- jcxz shkey2a ; z = none
- mov ax,keycode ; present keycode
- push ds
- pop es ; use data segment for es:di
- cld
- repne scasw ; is current keycode in the list?
- jne shkey2a ; ne = not in list
- sub di,2 ; correct for auto increment
- sub di,offset keylist
- mov listptr,di ; list pointer for existing definition
- pop cx
- pop di
- jmp shkey3 ; go process definition
-
- shkey2a:pop cx
- pop di
- mov dx,offset noxmsg ; say Self (no translation)
- mov ah,prstr
- int dos
- ret ; return to main show key loop
-
- shkey3: ; translations, get kind of.
- mov si,listptr
- test dirlist[si],verb ; defined as verb?
- jnz shkey6 ; nz = yes, go do that one
- test dirlist[si],strng ; defined as string?
- jz shkey3a ; z = no
- jmp shkey8 ; yes, do string display
- shkey3a:
- mov dx,offset ascmsg ; CHAR. say 'Ascii char:'
- mov ah,prstr
- int dos
- mov ax,dirlist [si] ; get type and char
- mov dl,al ; put char here for display
- push ax ; save here too
- mov ah,conout
- cmp dl,spc ; control code?
- jae shkey4 ; ae = no
- push dx
- mov dl,5eh ; show caret
- int dos
- pop dx
- add dl,'A'-1 ; add ascii bias
- shkey4: cmp dl,del ; DEL?
- jne shkey4a ; ne = no
- mov dl,'D' ; spell out DEL
- int dos
- mov dl,'E'
- int dos
- mov dl,'L'
- shkey4a:int dos
- mov dl,spc ; add a couple of spaces
- mov ah,conout
- int dos
- int dos
- mov dl,'\' ; add backslash before number
- int dos
- pop ax ; recover char
- xor ah,ah ; clear high byte
- call decout ; show decimal value
- ret ; return to main show key loop
-
- shkey6: mov ah,prstr ; VERB
- mov dx,offset verbmsg ; say 'verb'
- int dos
- mov si,listptr ; get verb index from director
- mov dx,dirlist[si]
- and dx,not(verb+strng) ; remove type bits, leaves verb number
- mov bx,offset kverbs ; table of verbs & actions
- mov al,byte ptr [bx] ; number of keywords
- xor ah,ah
- dec ax
- mov kwcnt,ax ; save number of last one here
- cmp dx,ax ; asking for more than we have?
- ja shkeyx ; a = yes, exit bad
- inc bx ; point to first slot
- xor cx,cx ; current slot number
- shkey6b:cmp cx,dx ; this slot?
- je shkey6c ; e = yes, print the text part
- ja shkeyx ; a = beyond, exit bad
- mov ax,[bx] ; get cnt (keyword length)
- add ax,4 ; skip count and two byte value
- add bx,ax ; bx = start of next keyword slot
- inc cx ; current keyword number
- jmp short shkey6b ; try another
- shkey6c:push cx
- mov cx,[bx] ; length of definition
- add bx,2 ; look at text field
- mov di,bx ; offset for printing
- call prtscr ; print counted string
- mov ah,conout
- mov dl,spc ; add a couple of spaces
- int dos
- int dos
- mov dl,'\' ; show verb name as \Kverb
- int dos
- mov dl,'K'
- int dos
- call prtscr ; print counted string, again
- pop cx
- ret ; return to main show key loop
-
- shkey8: mov ah,prstr ; STRING
- mov dx,offset strngmsg ; say String:
- int dos
- mov si,listptr ; get index from director
- mov bx,dirlist[si]
- and bx,not(verb+strng) ; remove type bits
- shl bx,1 ; index words
- mov si,sptable[bx] ; table of string offsets
- mov cx,word ptr [si] ; get string length
- add si,2 ; point to string text
- mov ah,conout
- shkey8a:cld
- lodsb ; get a byte
- cmp al,spc ; control code?
- jae shkey8b ; ae = no
- push ax
- mov dl,5eh ; show caret first
- int dos
- pop ax
- add al,40h ; convert to printable for display
- shkey8b:mov dl,al
- int dos ; display it
- loop shkey8a ; do another
- ret ; return to main show key loop
-
- shkeyx: pop bx ; restore reg
- clc ; return success
- ret
- SHKEY ENDP
-
- ;;; keyboard translator local support procedures, system independent
-
- ; Tstkeyw checks text word pointed to by si against table of keywords (pointed
- ; to by kverbs, made by mkeyw macro); returns in bx either action value or 0.
- ; Returns in kbtemp the number of the keyword and carry clear, or if failure
- ; returns kbtemp zero and carry set.
- ; Keyword structure is: dw cnt (length of string 'word')
- ; db 'word' (keyword string)
- ; dw value (value returned in bx)
- ; Make these with macro mkeyw such as mkeyw 'test',15 with the list of
- ; such keywords headed by a byte giving the number of keywords in the list.
- tstkeyw proc near
- push ax
- push cx
- push si
- mov verblen,0 ; verblen will hold verb length
- push si ; save user's verb pointer
- tstkw1: cld
- lodsb ; get a verb character
- cmp al,spc ; verbs are all non-spaces and above
- jbe tstkw2 ; be = done (space or control char)
- inc verblen ; count verb length
- jmp short tstkw1 ; printable char, look for more
- tstkw2: pop si ; pointer to verb
- mov bx,offset kverbs ; table of Kermit verb keywords
- mov al,byte ptr [bx] ; number of keywords
- xor ah,ah
- mov kwcnt,ax ; save number of keywords here
- inc bx ; point bx to first slot
- mov kbtemp,0 ; remember which keyword
-
- tstkw3: ; match table keyword and text word
- mov cx,verblen ; length of user's verb
- cmp [bx],cx ; compare length vs table keyword
- jne tstkw4 ; ne = not equal lengths, try another
- push si ; lengths match, how about spelling?
- push bx
- add bx,2 ; point at start of keyword
- tstkw3a:mov ah,byte ptr [bx] ; keyword char
- mov al,byte ptr [si] ; text char
- cmp ah,'A'
- jb tstkw3b ; b = control chars
- cmp ah,'Z'
- ja tstkw3b ; a = not upper case alpha
- add ah,'a'-'A' ; convert upper case to lower case
- tstkw3b:cmp al,'A'
- jb tstkw3c
- cmp al,'Z'
- ja tstkw3c
- add al,'a'-'A' ; convert upper case to lower case
- tstkw3c:cmp al,ah ; test characters
- jne tstkw3d ; ne = no match
- inc si ; move to next char
- inc bx
- loop tstkw3a ; loop through entire length
- tstkw3d:pop bx
- pop si
- jcxz tstkw5 ; z: cx = 0, exit with match;
- ; else select next keyword
- tstkw4: inc kbtemp ; number of keyword to test next
- mov cx,kbtemp
- cmp cx,kwcnt ; all done? Recall kbtemp starts at 0
- jae tstkwx ;ae = exhausted search, unsuccessfully
- mov ax,[bx] ; cnt (keyword length from macro)
- add ax,4 ; skip over count and two byte value
- add bx,ax ; bx = start of next keyword slot
- jmp tstkw3 ; do another comparison
-
- tstkw5: ; get action pointer
- mov ax,[bx] ; cnt (keyword length from macro)
- add ax,2 ; skip over count
- add bx,ax ; now bx points to dispatch value
- mov bx,[bx] ; bx holds dispatch value
- clc ; carry clear for success
- jmp short tstkwxx ; exit
- ret
- tstkwx: xor bx,bx ; exit when no match
- mov kbtemp,bx ; make verb number be zero too
- stc ; carry set for failure
- tstkwxx:pop si
- pop cx
- pop ax
- ret
- tstkeyw endp
-
- ; Insert asciiz string pointed to by si into string buffer stbuf.
- ; Reg cx has string length upon entry.
- ; Success: returns offset of first free byte (strmax) in string buffer stbuf,
- ; cx = type and Index of new string, and carry clear.
- ; Failure = carry set.
- insertst proc near
- push bx
- push dx
- push si
- push di
- push kbtemp ; save this variable too
- mov dx,cx ; save length of incoming string in dx
- mov bx,offset sptable ; table of string offsets
- mov kbtemp,0 ; slot number
- mov cx,maxstng ; number of entries, find an empty slot
- insert1:cmp word ptr[bx],0 ; slot empty?
- je insert2 ; e = yes
- inc kbtemp ; remember slot number
- add bx,2 ; look at next slot
- loop insert1 ; keep looking
- jmp short insert4 ; get here if no empty slots
- insert2: ; see if stbuf has sufficient space
- mov cx,dx ; length of new string to cx
- mov di,strmax ; offset of first free byte in stbuf
- add di,cx ; di = address where this string would end
- cmp di,offset stbuf+stbuflen ; beyond end of buffer?
- jae insert4 ; ae = yes, not enough room
- mov di,strmax ; point to first free slot in stbuf
- mov [bx],di ; fill slot with address offset of buffer
- push es
- push ds
- pop es ; point es:di to data segment
- cld
- mov [di],cx ; length of text for new string
- add di,2 ; move to next storage slot
- rep movsb ; copy string text
- pop es
- mov strmax,di ; offset of next free byte
- mov cx,kbtemp ; return new slot number with Director Index
- and cx,not(strng+verb) ; clear type bits
- or cx,strng ; say type is multi-char string
- clc ; say success
- jmp short insertx ; exit
- insert4:stc ; say no-can-do
- insertx:pop kbtemp
- pop di
- pop si
- pop dx
- pop bx
- ret
- insertst endp
-
- ; Remove (delete) string. Enter with listptr preset for director entry.
- ; Acts only on existing multi-char strings; recovers freed space.
- ; All registers preserved.
- remstr proc near
- push si
- mov si,listptr ; list pointer
- test dirlist[si],strng ; multi-char string?
- pop si
- jnz remst1 ; nz = a multi-char string
- ret ; else do nothing
- remst1: push ax
- push bx
- push cx
- push dx
- push si
- mov si,listptr
- mov ax,dirlist[si] ; Director table entry
- and ax,not(strng+verb) ; clear type bits, leave string's pointer
- mov dirlist[si],0 ; clear Director table entry
- shl ax,1 ; index words not bytes
- mov si,offset sptable ; list of string offsets in stbuf
- add si,ax ; plus index = current slot
- mov bx,[si] ; get offset of string to be deleted
- mov dx,bx ; save in dx for later
- mov cx,[bx] ; get length of subject string
- add cx,2 ; length word too, cx has whole length
- sub strmax,cx ; count space to be freed (adj end-of-buf ptr)
- mov word ptr [si],0 ; clear sptable of subject string address
- push cx ; save length of purged string
- push di ; save di
- push si
- push es ; save es
- push ds
- pop es ; setup es:di to be ds:offset of string
- mov di,dx ; destination = start address of purged string
- mov si,dx ; source = start address of purged string
- add si,cx ; plus string length of purged string.
- mov cx,offset stbuf+stbuflen ; 1 + address of buffer end
- sub cx,si ; 1 + number of bytes to move
- dec cx ; number of bytes to move
- jcxz remst2 ; z = none
- cld ; direction is forward
- rep movsb ; move down preserved strings
- remst2: pop es ; restore regs
- pop di
- pop si
- pop ax ; recover length of purged string (was in cx)
- mov bx,offset sptable ; string pointer table
- mov cx,maxstng ; max mumber of entries
- remst4: cmp [bx],dx ; does this entry occur before purged string?
- jbe remst5 ; be = before or equal, so leave it alone
- sub [bx],ax ; recompute address (remove old string space)
- remst5: add bx,2 ; look at next list entry
- loop remst4 ; do all entries in sptable
- pop si
- pop dx
- pop cx
- pop bx
- pop ax
- ret
- remstr endp
-
- shkfre proc near ; show free key & string defs & space
- push ax ; preserves all registers.
- push bx
- push cx
- push dx
- push kbtemp
- mov dx,offset fremsg
- mov ah,prstr
- int dos
- mov ax,maxkeys ; max number of key defs
- sub ax,nkeys ; number currently used
- call decout ; show the value
- mov ah,prstr
- mov dx,offset kyfrdef ; give key defs msg
- int dos
- mov bx,offset sptable ; table of string pointers
- mov cx,maxstng ; number of pointers
- mov kbtemp,0 ; number free
- shkfr1: cmp word ptr [bx],0 ; slot empty?
- jne shkfr2 ; ne = no
- inc kbtemp ; count free defs
- shkfr2: add bx,2 ; look at next slot
- loop shkfr1 ; do all of them
- mov ax,kbtemp ; number of free defs
- call decout ; display
- mov dx,offset stfrdef ; say free string defs
- mov ah,prstr
- int dos
- mov ax,offset stbuf+stbuflen+1 ; 1 + last byte in stbuf
- sub ax,strmax ; offset of last free byte in stbuf
- call decout
- mov dx,offset stfrspc ; give free space part of msg
- mov ah,prstr
- int dos
- pop kbtemp
- pop dx
- pop cx
- pop bx
- pop ax
- ret
- shkfre endp
-
- ; Initialize the keyboard tables at Kermit startup time. Optional procedure.
- ; Requires kbdinlst to be configured with mkeyw macro in the form
- ; mkeyw 'definition',keytype*256+keycode
- ; keytype is 0 for scan codes and non-zero for ascii.
- ; Returns normally.
- kbdinit proc near ; read keyword kbdinlst and setup
- or byte ptr kbcodes,80h ; say kbcodes not-initiated
- push ds ; initial keyboard assignments.
- pop es ; set es:di to data segment
- inc taklev ; pretend that we are in Take file
- kbdini0:mov si,offset kbdinlst ; start of list of definitions
- kbdini1:mov cx,[si] ; cnt field (keyword length of macro)
- jcxz kbdinix ; z = null cnt field = end of list
- add si,2 ; look at text field
- mov di,offset tranbuf ; where defkey expects text
- cld
- rep movsb ; copy cx chars to tranbuf
- mov byte ptr [di],0 ; insert null terminator
- mov ax,word ptr [si] ; get value field
- mov keycode,ax ; set key ident value
- push si
- call dfkey2 ; put dfkey to work
- pop si
- add si,2 ; point to next entry
- jmp kbdini1 ; keep working
- kbdinix:dec taklev ; reset Take file level
- call udkclear ; clear User Definable Keys
- ret
- kbdinit endp
- ;;; End of System Independent Procedures
-
- ;;; Begin System Dependent Procedures
-
- ; Read keyboard. System dependent.
- ; Return carry set if nothing at keyboard.
- ; If char present return carry clear with key's code in Keycode.
- ; If key is ascii put that in the low byte of Keycode and clear bit Scan in
- ; the high byte; otherwise, put the scan code in the lower byte and set bit
- ; Scan in the high byte. Uses dos keyboard reading.
- ; Modifies register ax.
- getkey proc near
- mov keycode,0 ; clear old keycode
- cmp dosflg,0 ; do ascii keyboard reading?
- jnz getky7 ; nz = yes, ascii
- jmp getky6 ; do scan code form
- ; ;;;;;;;; A S C I I ;;;;;;;;;
- getky7: test dosflg1,1 ; scan codes enabled?
- jz getky7a ; z = no, continue
- call dis_scan ; disable them
- getky7a:test byte ptr kbcodes,80h ; kbcodes initiated? [dan]
- jz getky5 ; z = yes [dan]
- push si
- call nrc2cp ; point SI at this code page to NRC
- mov nrcptr,si
- pop si
- push bx
- call cplatin ; code page to Latin1, BX gets ptr
- mov latinptr,bx
- call cpdecsg ; code page to DEC-MCS, BX gets ptr
- mov decmnptr,bx
- pop bx
- and byte ptr kbcodes,not 80h ; say kbcodes initiated
- getky5: call iseof ; is stdin at eof?
- jnc getky5k ; nc = not eof, get more
- mov al,trans.escchr ; Kermit's escape char
- mov byte ptr keycode,al ; save ascii char
- clc ; to get out gracefully at EOF
- ret ; and exit
-
- getky5k:push dx
- mov dl,0ffh ; DOS read operation
- mov ah,dconio ; from stdin
- int dos
- pop dx
- jnz getky5a ; nz = char available
- stc ; carry set = nothing available
- ret ; exit on no char
- getky5a:xor ah,ah
- cmp al,16 ; Control P?
- jne getky5b ; ne = no
- mov al,0a2h ; force F12 scan code, put on printer
- or keycode,scan ; ensure scan bit is set
- jmp short getky5c
- getky5b:cmp al,BS ; backspace key?
- jne getky5c ; ne = no
- ; or keycode,scan ; ensure scan bit is set
- getky5c:mov byte ptr keycode,al ; save ascii char
- clc ; carry clear = got a char
- ret ; and exit
- ; ;;;;;; S C A N C O D E ;;;;;;
- getky6: test dosflg1,1 ; scan codes enabled?
- jnz getky6a ; nz = yes, continue
- call ena_scan ; enable them
- getky6a:test byte ptr kbcodes,80h ; kbcodes initiated? [dan]
- jz getky6b ; z = yes [dan]
- mov kbcodes,0001h ; low byte = status, high = read char
- push si
- call nrc2cp ; point SI at this code page to NRC
- mov nrcptr,si
- pop si
- push bx
- call cplatin ; code page to Latin1, BX gets ptr
- mov latinptr,bx
- call cpdecsg ; code page to DEC-MCS, BX gets ptr
- mov decmnptr,bx
- pop bx
- getky6b:call iseof ; is stdin at eof?
- jnc getky6c ; nc = not eof, get more
- mov al,trans.escchr ; Kermit's escape char
- mov byte ptr keycode,al ; save ascii char
- clc ; to get out gracefully at EOF
- ret ; and exit
- getky6c:push dx
- mov dl,0ffh ; DOS read operation
- mov ah,dconio ; from stdin
- int dos
- pop dx
- jnz getky6d ; nz = char available
- stc ; carry set = nothing available
- ret ; exit on no char
- getky6d:call fixflg ; go set keycode flags in ax
- cmp al,80h ; start of special keys
- jb getky6g ; go make these pure ascii
- getky6e:or ax,scan ; set the scan bit
- getky6f:mov keycode,ax
- clc
- ret
- getky6g:push cx
- mov cx,shift
- or cx,control
- not cx
- and ax,cx ; clear shift and control bits
- pop cx
- jmp short getky6f
- getkey endp
-
- ; Return modified char code, depending on SET TERM CHAR-SET and active
- ; Code Page. Enter and exit with char in AL.
- xltkey proc near
- cmp al,' ' ; control character?
- jb xltkey2 ; b = yes, do not translate
- cmp flags.xltkbd,0 ; keyboard translation is off?
- je xltkey2 ; e = yes
- cmp vtemu.vtchset,0 ; NRC's, using ASCII already?
- je xltkey2 ; e = yes, use char in AL
- cmp vtemu.vtchset,12 ; 1-12 for NCRs?
- ja xltkey3 ; a = no
- push si
- push di
- push ax
- mov si,nrcptr ; point SI at this code page to NRC
- pop ax
- mov di,si ; start of table are ASCII chars
- mov cl,vtemu.vtchset ; get set number (1-12)
- xor ch,ch
- sub di,cx ; minus one byte per set
- shl cx,1 ; 15 bytes per NRC entry
- shl cx,1
- shl cx,1
- shl cx,1
- add di,cx ; +16, source, point at this entry
- mov cx,12 ; do first 12 bytes of them
- push es
- push ds
- pop es
- cld
- repne scasb ; look for this byte code in table
- pop es
- jne xltkey1 ; ne = not found, use char in AL
- inc cx
- sub cx,12 ; compute char index
- neg cx
- add si,cx ; index into ASCII table
- mov al,[si] ; get matching ASCII char (set 0)
- xltkey1:pop di
- pop si
- xltkey2:ret
- ; LATIN1 set
- xltkey3:test al,80h ; high bit set?
- jz xltkey2 ; z = no, no translation
- cmp vtemu.vtchset,15 ; set term character-set LATIN1?
- jne xltkey4 ; ne = no
- and al,not 80h ; remove high bit
- push bx
- mov bx,latinptr ; Code Page to Latin1
- xlatb ; translate to Latin1 in AL
- pop bx
- ret
- xltkey4:cmp vtemu.vtchset,16 ; set term character-set DEC-MCS?
- jne xltkey2 ; ne = no
- and al,not 80h ; remove high bit
- push bx
- mov bx,DECmnptr ; Code Page to DEC-MCS
- xlatb ; translate to DEC-MCS in AL
- pop bx
- ret
- xltkey endp
-
-
- ; Do any local processing after reading a key during active translation
- ; Avoids same actions if a key is being defined or shown.
- postkey proc near
- ; Key Click code for VT102 emulator
- cmp flags.vtflg,0 ; emulating? (0 = no)
- je postke1 ; e = extra clicks not available
- test vtemu.vtflgst,vskeyclick ; flags from SET TERM
- jz postke1 ; z = extra clicks not wanted
- call vclick ; click, what else?
- postke1:ret
- postkey endp
-
- ;keycom sends commands in dl to the Z-100 keyboard processor
- keycom proc near
- in al,keystat ; check status
- test al,KPR ; keyboard ready?
- jnz keycom ; keep trying if not ready
- mov al,dl ; we need command here
- out keycmd,al ; do it
- ret
- keycom endp
-
- ;fixflg updates ax by seting the proper shift keycode flags in ah
- ;enter with true Z-100 ascii scan code in al
- ;returns with ax updated per keycode standards, except bit scan not set
- fixflg proc near
- xor ah,ah ; we need it clean
- push di ; search list z10keyl for this keycode
- push cx ; save some registers
- push es
- mov di,offset z10keyl ; list of defined keycode bytes
- mov cx,lz10keyl ; number of bytes to examine
- push ds
- pop es ; make es:di point to data segment
- cld
- repne scasb ; find keycode in list
- pop es ; restore regs
- je fixflg1 ; e = found, work with present di
- pop cx ; restore original cx
- pop di ; restore original di
- ret ; char is already in al
- fixflg1:neg cx ; subtract cx from
- add cx,lz10keyl ; we went this far into the table
- and cx,3 ; we need these bits
- cmp cx,1 ; nothing?
- jz fixflg4 ; done
- cmp cx,2 ; shift?
- jnz fixflg2 ; no, go check control
- or ax,shift ; shift, set 200
- jmp fixflg4 ; done
- fixflg2:cmp cx,3 ; control?
- jnz fixflg3 ; no, jump
- or ax,control ; yes, control, set 400
- jmp fixflg4 ; done
- fixflg3:or ax,shift ; must be
- or ax,control ; both of these
- fixflg4:pop cx
- pop di
- ret
- fixflg endp
-
- code ends
- end
-